/*
    This file is part of OpenWordle.

    OpenWordle is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    OpenWordle is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with OpenWordle.  If not, see <http://www.gnu.org/licenses/>.
*/

public class WordleLayout
{
  PApplet applet;
  color backgroundColor;
  Random rand;
  PFont font;

  public WordleLayout( PApplet app )
  {
    this( app, color(0) );
  }
  
  public WordleLayout( PApplet app, color bkgrnd )
  {
    applet = app;
    backgroundColor = bkgrnd;
    rand = new Random();
  }
  
  void doWordleLayout( Word word, PFont font )
  {
    this.font = font;
    applet.textFont( font );
    applet.textAlign( CENTER, CENTER );
    
    makeInitialPosition( word );
    
    while( intersects( word ) )
      updatePosition( word );
  }
  
  void paintWord( Word word )
  {
    paintWord( word, applet.g );
  }
  
  void paintWord( Word word, PGraphics graphics )
  {
    graphics.beginDraw();
    graphics.pushMatrix();
    graphics.translate( word.x, word.y );
    graphics.rotate( word.angle );
    graphics.textFont( font );
    graphics.textAlign( CENTER, CENTER );
    graphics.text( word.toString(), 0, 0 );
    graphics.popMatrix();
    graphics.endDraw();
  }
  
  void makeInitialPosition( Word word )
  {
    // randomize angle (in this case, horizontal:vertical)
    if ( random(1.0) < 0.5 )
      word.angle = -HALF_PI;
    else
      word.angle = 0;

    float wWidth = applet.textWidth( word.toString() ) / 2;
    float wHeight = applet.textAscent();
    
    // TODO: check for vertical out-of-bounds

    double x, y;
    do
    {
      x = rand.nextGaussian() * applet.width/8 + applet.width/2;
      y = rand.nextGaussian() * applet.height/8 + applet.height/2;
    } 
    while( x > applet.width - wWidth || x < wWidth || y < 0 || y > applet.height );

    word.x = (float)x;
    word.y = (float)y;
  }

  void updatePosition( Word word )
  {
    // TODO: spiral out

    // for now, use random numbers
    makeInitialPosition( word );
  }

  boolean intersects( Word word )
  {
    color white = color(255);
    // create new word buffer
    PGraphics newWordBuffer = applet.createGraphics( applet.width, applet.height, JAVA2D );
    drawBackground( newWordBuffer );
    newWordBuffer.textAlign( CENTER, CENTER );
    newWordBuffer.fill( white );
    paintWord( word, newWordBuffer );

    // test each pixel
    // TODO: optimize by starting search at new word's top
    int top, bottom;
    if ( word.angle != 0 )
    {
      int halfTextWidth = (int)(applet.textWidth( word.toString() ) / 2);
      top = (int)applet.max( word.y - halfTextWidth, 0 );
      bottom = (int)(word.y + halfTextWidth);
    }
    else
    {
      top = (int)(word.y - applet.textAscent());
      bottom = (int)(word.y + applet.textAscent());
    }

    for( int y = top; y < bottom && y < applet.height; y++ )
    {
      for( int x = 0; x < applet.width; x++ )
      {
        int c1 = applet.get( x, y );
        int c2 = newWordBuffer.get( x, y );
        if ( c1 != backgroundColor && c2 != backgroundColor )
          return true;
      }
    }

    return false;
  }
  
  private void drawBackground( PGraphics buffer )
  {
    buffer.beginDraw();
    buffer.background( backgroundColor );
    buffer.endDraw();
  }

}

